import { _decorator, Component, Node, Prefab, CCInteger, instantiate, v3, CCObject, Vec3, game, LabelComponent, NodePool, AudioSourceComponent, ButtonComponent, Game } from "cc";
import { PlayerController } from "../PlayerController";
const { ccclass, property } = _decorator;
enum BlockType{
    BT_NONE,
    BT_STONE
}
enum GameState {
    GS_INIT,
    GS_PLAYING,
    GS_END
}
@ccclass("GameManager")
export class GameManager extends Component {
    /* class member could be defined like this */
    // dummy = '';

    /* use `property` decorator if your want the member to be serializable */
    // @property
    // serializableDummy = 0;
    @property({type: Prefab})
    public cubePrefab: Prefab = null;
    @property({type: CCInteger})
    public roadLength: Number = 50;
    @property({type: PlayerController})
    public playerCtrl: PlayerController = null;
    @property({type: LabelComponent})
    public scoreLabel: LabelComponent = null;
    @property({type: Node})
    public canvasNode: Node = null;
    @property({type: Prefab})
    public overMenuPrefab: Prefab = null;

    @property({type: Node})
    public startMenu: Node = null;
    private _road: number[] = [];

    private _curState: GameState = GameState.GS_INIT;
    // 节点池中的对象数量
    private poolLength: number = 15;
    // 节点池对象
    private pool: NodePool = null;

    // 英雄当前的位置
    private curPos: Vec3 = v3();
    // 到游戏结束时候总共走的步数和时间
    private steps: number = 0;
    private totalTime: number = 0;
    
    private gameOverNode: Node = null;

    start () {
        // 创建池
        this.pool = new NodePool();
        this.createBlockPool();
        // Your initialization goes here.
        this.curState = GameState.GS_INIT;
        this.playerCtrl.node.on("jumpEnd",this.playerJumpEnd,this);
    }
    private playerJumpEnd(data: any): void {
        console.log("data is ",data);
        this.steps = data;
        this.scoreLabel.node.getComponent(LabelComponent).string = data.toString();
        if(data >= 5) {
            let curX = this.playerCtrl.node.getPosition().x;
            // 屏幕外的方块有
            let num: number = 0;
            let moveNodeArr: Node[] = [];
            for(let i = 0; i < this.node.children.length; i++) {
                if(this.node.children[i].getPosition().x < curX - 4) {
                    num++;
                    moveNodeArr.push(this.node.children[i]);
                }
            }
            // console.log("gameManager's leng is ",this.node.children.length);
            // console.log("num is ",num);
            for(let j = 0; j < num; j++) {
                if(this._road[this._road.length - 1] === BlockType.BT_NONE) {
                    this._road.push(BlockType.BT_STONE);
                } else {
                    this._road.push(Math.floor(Math.random() * 2));
                }
            }
            console.log("road is ",this._road);
            for(let k = 0; k < moveNodeArr.length; k++) {
                if(this._road[k + this._road.length - num] === 1) {
                    // this.node.children[this.moveIndex].setPosition(i,-1.5,0);
                    moveNodeArr[k].setPosition(k + this._road.length - num,-1.5,0);
                }
            }
        }
    }
    public init(): void {
        // this.node.removeAllChildren();
        this.startMenu.active = true;
        this.playerCtrl.gameOver = false;
        this.generateRoad();
        this.playerCtrl.setInputActive(false);
        this.playerCtrl.node.setPosition(v3(1,0,0));
        // 初始化一些数据
        this.totalTime = 0;
        // this.startMenu.getChildByName();
        this.steps = 0;
        // 计分版设置为0
        this.scoreLabel.node.getComponent(LabelComponent).string = "0";
        this.playerCtrl.stepCount = 0;
        if(this.gameOverNode) {
            // 销毁gameOverNode
            this.gameOverNode.destroy();
        }
    }
    // 设置游戏状态
    set curState(value: GameState) {
        switch(value) {
            case GameState.GS_INIT:
                this.init();
                break;
            case GameState.GS_PLAYING:
                this.startMenu.active = false;
                let self = this;
                setTimeout(() => {
                    // 开始监听鼠标事件
                    self.playerCtrl.setInputActive(true);
                },0.1);
                break;
            case GameState.GS_END:
                // game.pause();
                this.playerCtrl.setInputActive(false);
                this.gameOverNode = instantiate(this.overMenuPrefab);
                this.gameOverNode.getChildByName("stepsNum").getComponent(LabelComponent).string = this.steps.toString();
                this.gameOverNode.getChildByName("timeNum").getComponent(LabelComponent).string = this.totalTime.toFixed(2) + "s";
                this.canvasNode.addChild(this.gameOverNode);
                this.gameOverNode.setPosition(v3(0,0,0));
                this.gameOverNode.getChildByName("restart").on("click",this.restartGame,this);
                this.node.getComponent(AudioSourceComponent).play();
                break;         
        }
        this._curState = value;
    }
    private restartGame(button: any): void {
        this.playerCtrl.begin = false;
        // 回收节点池中的数据
        // for(let i = 0; i < this.node.children.length; i++) {
        //     // put操作自动从父节点上移除该节点所以this.node.children.length是变化的
        //     this.pool.put(this.node.children[i]);
        // }
        while(this.node.children.length > 0) {
            this.pool.put(this.node.children[this.node.children.length - 1]);
        }
        // 恢复一些初始好的数据
        this.curState = GameState.GS_INIT;
        this._curState = GameState.GS_INIT;
        
    }   
    public btnEvent(e: Event,data: any): void {
        if(this._curState !== GameState.GS_END) {
            switch(data) {
                case "play":
                    this.curState = GameState.GS_PLAYING;
                    break;
                case "one":
                    this.playerCtrl.jumpByStep(1);
                    break;
                case "two":
                    this.playerCtrl.jumpByStep(2);
                    break;        
            }
        }
    }
    private generateRoad(): void {
        this.node.removeAllChildren();
        this._road = [];
        this._road.push(BlockType.BT_NONE);

        for(let i = 1; i < this.poolLength; i++) {
            if(this._road[i - 1] === BlockType.BT_NONE) {
                this._road.push(BlockType.BT_STONE);
            } else {
                this._road.push(Math.floor(Math.random() * 2));
            }
        }
        for(let j = 0; j < this._road.length; j++) {
            let block: Node = this.spawnBlockByType(this._road[j]);
            if(block) {
                this.node.addChild(block);
                block.setPosition(j,-1.5,0);
            }
        }
        // this.playerCtrl.node.setPosition(2,0,0);
        // this.playerCtrl.jumpByStep(-1);
    }
    private spawnBlockByType(type: BlockType) {
        let block = null;
        switch(type) {
            case BlockType.BT_STONE:
                block = this.pool.get();
                break;
            case BlockType.BT_NONE:
                break;    
        }
        return block;
    }
    // 创建节点池存放需要移动的地板
    private createBlockPool(): void {
        for(let i = 0; i < this.poolLength; i++) {
            let block: Node = instantiate(this.cubePrefab);
            this.pool.put(block);
        }
    }

    update (deltaTime: number) {
        if(this._curState === GameState.GS_PLAYING) {
            this.totalTime += deltaTime;
        }
       // 主角跳跃完毕后检测游戏是否结束
       if(!this.playerCtrl._isMoving) {
           let curX = this.playerCtrl.node.getPosition().x;
           if(this._road[curX] === BlockType.BT_NONE || this.playerCtrl.gameOver) {
               this.playerCtrl.stopTime = 0;
               if(this._curState !== GameState.GS_END) {
                   this.curState = GameState.GS_END;
               }
               if(this.playerCtrl.gameOver) {
                   console.log("静止时间超过1秒了");      
               }
           }
       }
    }
}
